package com.example.smartcity_poverty.logic

import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.example.smartcity_poverty.logic.network.AppApi
import com.example.smartcity_poverty.logic.network.ServiceNET.Companion.create
import com.example.smartcity_poverty.logic.network.TakeOutApi
import com.example.smartcity_poverty.logic.util.Util.show
import kotlinx.coroutines.*
import java.lang.Exception
import java.lang.RuntimeException
import kotlin.coroutines.CoroutineContext

/**
 *  created by ikun
 *  ANDROID STUDIO - version 4.0
 *  email: jinkunwei41@gmail.com
 * --------------------------------
 *  处理网络回调
 **/
object Repository {

    //
    val api = create<AppApi>()

    // 外卖订餐Api
    val toApi = create<TakeOutApi>()

    //获取轮播图
    fun getBanner(map: Map<String, Int>) = fire(Dispatchers.IO) {
        val place = api.getBanner(map)
        if (place.code == "200") {
            Result.success(place)
        } else {
            Result.failure(RuntimeException("加载轮播图出错！"))
        }
    }


    /**
     * 全部服务
     */
    fun getMore() = fire(Dispatchers.IO) {
        val place = api.getMore()
        if (place.code == 200) {
            Result.success(place)
        } else {
            Result.failure(RuntimeException("加载全部服务出错！"))
        }
    }


    /**
     * 获取新闻
     */
    fun getNews(hot: String?, type: String?) = fire(Dispatchers.IO) {
        val place = api.getHot(hot, type)
        if (place.code == 200) Result.success(place)
        else Result.failure(RuntimeException("加载热门主题失败！"))
    }




    // --------------------------------------------------------------
    /**
     * 停车场
     */

    /**
     * 获取停车场列表
     */
    fun getStopWhereAll() = fire(Dispatchers.IO){
        val place = api.getStopWhereAll()
        if (place.code == 200){
            Result.success(place)
        }else {
            "出错！".show()
            Result.failure(RuntimeException("加载列表出错！"))
        }
    }



    /**
     * 查询停车记录列表
     */
    fun getSWAll(inputTime: String) = fire(Dispatchers.IO){
        val place = api.getStopWhereTime(inputTime)
        if (place.code == 200) Result.success(place)
        else {
            "加载停车记录出错！".show()
            Result.failure(RuntimeException("加载停车记录出错！"))
        }
    }



    // ------------------------------------------
    /**
     * 活动管理
     */

    /**
     * 获取轮播图
     */
    fun getHBanner() = fire(Dispatchers.IO){
        val place = api.getHBanner()
        if (place.code == "200") Result.success(place)
        else Result.failure(RuntimeException("加载轮播图出错！"))
    }


    // 获取活动列表
    fun getHList(categoryId: Int) = fire(Dispatchers.IO){
        val place = api.getHList(categoryId)
        if (place.code == 200){
            Result.success(place)
        }else Result.failure(RuntimeException("加载列表出错！"))
    }

    // 获取评论
    fun getHListUserAll(activityId: Int) = fire(Dispatchers.IO){
        val place = api.getListUserAll(activityId)
        if (place.code == 200) Result.success(place)
        else Result.failure(RuntimeException("加载评论失败！"))
    }



    // ---------------------------------------------------------------
    /**
     * 数字图书馆
     */

    // 获取图书馆列表
    fun getNBList(token: String) = fire(Dispatchers.IO){
        val place = api.getNbList(token)
        if (place.code == 200) Result.success(place)
        else Result.failure(RuntimeException("加载图书馆列表出错！"))
    }


    // 获取图书馆评论
    fun getNBUserAll(token: String, id: Int) = fire(Dispatchers.IO){
        val place = api.getNumberBookUserAll(token, id)
        Log.d("NET", "getNBUserAll: ----> ${place.msg}")
        if (place.code == 200) {
            Result.success(place)
        }
        else Result.failure(RuntimeException("加载评论失败！"))
    }












    /**
     * 封装自动构建返回LiveData
     */
    private fun <E> fire(
        context: CoroutineContext,
        black: suspend () -> Result<E>
    ) : MutableLiveData<Result<E>> {
        val liveData = MutableLiveData<Result<E>>()
        val scope = CoroutineScope(context)
        // 开启协程
        scope.launch {
            try {
                val result = black.invoke()
                liveData.postValue(result)
            }catch (e: Exception){
                liveData.postValue(Result.failure(e))
            }
        }
        return liveData
    }

    /**
     * 协程封装
     */
    fun coroutine(
        context1: CoroutineContext = Dispatchers.IO,
        black: suspend CoroutineScope.() -> Unit
    ): Job {
        return CoroutineScope(context1).launch {
            try {
                coroutineScope {
                    black()
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}